home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / gui / bgui11b.lha / demos / multicol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-20  |  35.4 KB  |  844 lines

  1. ;/*
  2. dcc MultiCol.c -proto -mi -ms -mRR -lbgui
  3. quit
  4. */
  5. /*
  6. **         $RCSfile: multicol.c,v $
  7. **      Description: Shows you how to code a multi-column listview
  8. **                   object using the hooks that the listview class
  9. **                   provide.
  10. **        Copyright: (C) Copyright 1994 Jaba Development.
  11. **                   (C) Copyright 1994 Jan van den Baard.
  12. **                   All Rights Reserved.
  13. **
  14. **          $Author: jaba $
  15. **        $Revision: 1.3 $
  16. **            $Date: 1994/11/20 13:06:11 $
  17. **/
  18.  
  19. #include <exec/types.h>
  20. #include <exec/memory.h>
  21. #include <dos/dos.h>
  22. #include <dos/exall.h>
  23. #include <libraries/bgui.h>
  24. #include <libraries/bgui_macros.h>
  25. #include <utility/hooks.h>
  26.  
  27. #include <clib/alib_protos.h>
  28. #include <clib/macros.h>
  29.  
  30. #include <proto/exec.h>
  31. #include <proto/intuition.h>
  32. #include <proto/graphics.h>
  33. #include <proto/dos.h>
  34. #include <proto/bgui.h>
  35.  
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <stdio.h>
  39.  
  40. /*
  41. **      SAS<->DICE muck.
  42. **/
  43. #ifdef _DCC
  44. #define SAVEDS __geta4
  45. #define ASM
  46. #define REG(x) __ ## x
  47. #else
  48. #define SAVEDS __saveds
  49. #define ASM __asm
  50. #define REG(x) register __ ## x
  51. #endif
  52.  
  53. /*
  54. **      This is the data were going to add
  55. **      to the listview object. It is a simple
  56. **      structure in which the file-information
  57. **      is stored. This data is created in the
  58. **      LISTV_Resource hook from a pointer
  59. **      to a ExAllData structure.
  60. **/
  61. typedef struct {
  62.         UBYTE                   fi_FileName[ 108 ];
  63.         UBYTE                   fi_Size[ 11 ];
  64.         UBYTE                   fi_Date[ 32 ];
  65.         BOOL                    fi_IsDir;
  66. } FILEINFO;
  67.  
  68. /*
  69. **      The LISTV_Resource hook is used to create
  70. **      the FILEINFO structures from a struct ExAllData
  71. **      at create time. At delete time the FILEINFO
  72. **      structure is simply deallocated.
  73. **/
  74. SAVEDS ASM APTR ResourceHookFunc( REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct lvResource *lvr )
  75. {
  76.         struct ExAllData        *ead;
  77.         FILEINFO                *fi;
  78.         struct DateTime          dt;
  79.         APTR                     return_code = NULL;
  80.  
  81.         /*
  82.         **      What must we do?
  83.         **/
  84.         switch ( lvr->lvr_Command ) {
  85.  
  86.                 case    LVRC_MAKE:
  87.                         /*
  88.                         **      Create a FILEINFO structure.
  89.                         **      BGUI has passed us a pointer to a
  90.                         **      ExAllData structure. Here we
  91.                         **      convert it to a FILEINFO structure
  92.                         **      which, eventually, get's added to
  93.                         **      the listview.
  94.                         **/
  95.                         if ( fi = ( FILEINFO * )AllocVec( sizeof( FILEINFO ), MEMF_PUBLIC )) {
  96.                                 /*
  97.                                 **      Pick up the ExAllData.
  98.                                 **/
  99.                                 ead = ( struct ExAllData * )lvr->lvr_Entry;
  100.                                 /*
  101.                                 **      Copy the name.
  102.                                 **/
  103.                                 strcpy( &fi->fi_FileName[ 0 ], ead->ed_Name );
  104.                                 /*
  105.                                 **      Format the size text. We can do all sorts of
  106.                                 **      fancy stuff here like using the locale.library
  107.                                 **      formatting stuff but hey, it's just a demo ;)
  108.                                 **/
  109.                                 if ( ead->ed_Type < 0 ) {
  110.                                         fi->fi_IsDir = FALSE;
  111.                                         sprintf( &fi->fi_Size[ 0 ], "%ld", ead->ed_Size );
  112.                                 } else {
  113.                                         fi->fi_IsDir = TRUE;
  114.                                         strcpy( &fi->fi_Size[ 0 ], "(dir)" );
  115.                                 }
  116.                                 /*
  117.                                 **      Convert the date to a string.
  118.                                 **/
  119.                                 dt.dat_Stamp    = *(( struct DateStamp * )&ead->ed_Days );
  120.                                 dt.dat_Format   = FORMAT_CDN;
  121.                                 dt.dat_Flags    = DTF_SUBST | DTF_FUTURE;
  122.                                 dt.dat_StrDay   = NULL;
  123.                                 dt.dat_StrDate  = &fi->fi_Date[ 0 ];
  124.                                 dt.dat_StrTime  = NULL;
  125.                                 /*
  126.                                 **      Format date.
  127.                                 **/
  128.                                 DateToStr( &dt );
  129.                                 /*
  130.                                 **      Return a pointer to the created
  131.                                 **      FILEINFO structure.
  132.                                 **/
  133.                                 return_code = ( APTR )fi;
  134.                         }
  135.                         break;
  136.  
  137.                 case    LVRC_KILL:
  138.                         /*
  139.                         **      Simply deallocate the FILEINFO
  140.                         **      structure which has been created with
  141.                         **      LVRC_MAKE above.
  142.                         **/
  143.                         FreeVec( lvr->lvr_Entry );
  144.                         break;
  145.         }
  146.         /*
  147.         **      Pointer to FILEINFO or NULL.
  148.         **/
  149.         return( return_code );
  150. }
  151.  
  152. /*
  153. **      The listview will have three columns.
  154. **
  155. **      Name            Size            Date
  156. **
  157. **      The following globals will contain the maximum
  158. **      width of each of these columns.
  159. **/
  160. UWORD   MaxName, MaxSize, MaxDate;
  161.  
  162. /*
  163. **      This global stores the total width of the
  164. **      listview drawing area.
  165. **/
  166. UWORD   TotalWidth = 0;
  167.  
  168. /*
  169. **      This boolean determines wether the hook must
  170. **      re-compute the column sizes.
  171. **/
  172. BOOL    ReCompCols = TRUE;
  173.  
  174. /*
  175. **      We use 16 pixels as a minimum inner-column spacing.
  176. **/
  177. #define INNER_SPACE                     16
  178.  
  179. /*
  180. **      This routine re-computes the minimum column
  181. **      sizes when necessary.
  182. **/
  183. VOID ReComputeColumns( struct RastPort *rp, Object *obj, UWORD list_width )
  184. {
  185.         FILEINFO                        *fi;
  186.         UWORD                            tmp, total;
  187.  
  188.         /*
  189.         **      A re-computation is necessary when:
  190.         **
  191.         **      1) The ReCompCols flag is TRUE.
  192.         **      2) The with of the listview has changed.
  193.         **/
  194.         if ( ReCompCols || ( TotalWidth != list_width )) {
  195.                 /*
  196.                 **      Our listview also has a title entry.
  197.                 **      Here we compute the default column
  198.                 **      sizes accoording to this title.
  199.                 **/
  200.                 MaxName = TextLength( rp, "Name:", 6 ) + INNER_SPACE;
  201.                 MaxSize = TextLength( rp, "Size:", 6 ) + INNER_SPACE;
  202.                 MaxDate = TextLength( rp, "Date:", 6 );
  203.                 /*
  204.                 **      Now we loop through the entries to find
  205.                 **      out the largest width of the three columns.
  206.                 **/
  207.                 if ( fi = ( FILEINFO * )FirstEntry( obj )) {
  208.                         /*
  209.                         **      Loop until all are done.
  210.                         **/
  211.                         while ( fi ) {
  212.                                 /*
  213.                                 **      Compute width of the Name: column
  214.                                 **      for this entry.
  215.                                 **/
  216.                                 tmp = TextLength( rp, &fi->fi_FileName[ 0 ], strlen( &fi->fi_FileName[ 0 ] )) + INNER_SPACE;
  217.                                 /*
  218.                                 **      Is it bigger than the last one?
  219.                                 **      If so store it.
  220.                                 **/
  221.                                 if ( tmp > MaxName ) MaxName = tmp;
  222.                                 /*
  223.                                 **      Compute width of the Size: column
  224.                                 **      for this entry.
  225.                                 **/
  226.                                 tmp = TextLength( rp, &fi->fi_Size[ 0 ], strlen( &fi->fi_Size[ 0 ] )) + INNER_SPACE;
  227.                                 /*
  228.                                 **      Is it bigger than the last one?
  229.                                 **      If so store it.
  230.                                 **/
  231.                                 if ( tmp > MaxSize ) MaxSize = tmp;
  232.                                 /*
  233.                                 **      Compute width of the Date: column
  234.                                 **      for this entry.
  235.                                 **/
  236.                                 tmp = TextLength( rp, &fi->fi_Date[ 0 ], strlen( &fi->fi_Date[ 0 ] ));
  237.                                 /*
  238.                                 **      Is it bigger than the last one?
  239.                                 **      If so store it.
  240.                                 **/
  241.                                 if ( tmp > MaxDate ) MaxDate = tmp;
  242.                                 /*
  243.                                 **      Pick up the next entry.
  244.                                 **/
  245.                                 fi = ( FILEINFO * )NextEntry( obj, fi );
  246.                         }
  247.                 }
  248.                 /*
  249.                 **      Compute the total columns width.
  250.                 **/
  251.                 total = MaxName + MaxSize + MaxDate;
  252.                 /*
  253.                 **      If there's room left over we
  254.                 **      distribute it between the columns so
  255.                 **      we get a nice even spacing between
  256.                 **      them.
  257.                 **/
  258.                 if ( list_width > total ) {
  259.                         MaxName += ( list_width - total ) >> 1;
  260.                         MaxSize += ( list_width - total ) >> 1;
  261.                 }
  262.                 /*
  263.                 **      All done. Set the re-compute flag to
  264.                 **      FALSE and store the list width.
  265.                 **/
  266.                 ReCompCols = FALSE;
  267.                 TotalWidth = list_width;
  268.         }
  269. }
  270.  
  271. /*
  272. **      The default DrawInfo pens. Just in case we don't
  273. **      get them from the system.
  274. **/
  275. UWORD   DefDriPens[] = {
  276.         0, 1, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1 };
  277.  
  278. /*
  279. **      Listview rendering hook. Here's where the magic starts ;)
  280. **/
  281. SAVEDS ASM UBYTE *DisplayHookFunc( REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct lvRender *lvr )
  282. {
  283.         struct TextExtent               te;
  284.         UBYTE                          *str;
  285.         FILEINFO                       *fi = ( FILEINFO * )lvr->lvr_Entry;
  286.         UWORD                          *pens, numc, w, l, cw, h;
  287.  
  288.         /*
  289.         **      Pick up the DrawInfo pen array.
  290.         **/
  291.         pens = lvr->lvr_DrawInfo ? lvr->lvr_DrawInfo->dri_Pens : DefDriPens;
  292.         /*
  293.         **      Pick up the width of the list.
  294.         **/
  295.         w = lvr->lvr_Bounds.MaxX - lvr->lvr_Bounds.MinX + 1;
  296.         /*
  297.         **      Pick up the list left-edge;
  298.         **/
  299.         l = lvr->lvr_Bounds.MinX;
  300.         /*
  301.         **      Pick up the height of the entry.
  302.         **/
  303.         h = lvr->lvr_Bounds.MaxY - lvr->lvr_Bounds.MinY + 1;
  304.  
  305.         /*
  306.         **      First we render the background.
  307.         **/
  308.         SetAPen( lvr->lvr_RPort, lvr->lvr_State == LVRS_SELECTED ? pens[ FILLPEN ] : pens[ BACKGROUNDPEN ] );
  309.         SetDrMd( lvr->lvr_RPort, JAM1 );
  310.  
  311.         RectFill( lvr->lvr_RPort, lvr->lvr_Bounds.MinX,
  312.                                   lvr->lvr_Bounds.MinY,
  313.                                   lvr->lvr_Bounds.MaxX,
  314.                                   lvr->lvr_Bounds.MaxY );
  315.  
  316.         /*
  317.         **      When we are passed a NULL entry pointer
  318.         **      we are presumed to render the title. If your
  319.         **      listview does not have a title simply
  320.         **      recompute the columns and return NULL.
  321.         **      We have a title so here we go.
  322.         **/
  323.         if ( ! fi ) {
  324.                 /*
  325.                 **      Recompute the column sizes. The routine
  326.                 **      itself will decide if it's necessary.
  327.                 **/
  328.                 ReComputeColumns( lvr->lvr_RPort, obj, w );
  329.                 /*
  330.                 **      Set the pen for the title-entry.
  331.                 **/
  332.                 SetAPen( lvr->lvr_RPort, pens[ FILLPEN ] );
  333.         } else {
  334.                 /*
  335.                 **      Set the pen for a non-title entry. Ofcourse
  336.                 **      we can (should?) differenciate between normal and
  337.                 **      selected here but I wont ;)
  338.                 **/
  339.                 if ( fi->fi_IsDir ) SetAPen( lvr->lvr_RPort, pens[ HIGHLIGHTTEXTPEN ] );
  340.                 else                SetAPen( lvr->lvr_RPort, pens[ TEXTPEN ] );
  341.         }
  342.         /*
  343.         **      Obtain Name: column width. We check it against the
  344.         **      total list width so we do not go outside the
  345.         **      given area.
  346.         **/
  347.         cw = MIN( MaxName, w );
  348.  
  349.         /*
  350.         **      Pick up the name string or, when this
  351.         **      is a title call, the string "Name:".
  352.         **/
  353.         str = fi ? &fi->fi_FileName[ 0 ] : ( UBYTE * )"Name:";
  354.  
  355.         /*
  356.         **      Compute the number of character we
  357.         **      can render.
  358.         **/
  359.         numc = TextFit( lvr->lvr_RPort, str, strlen( str ), &te, NULL, 0, cw, h );
  360.  
  361.         /*
  362.         **      If the number of characters is
  363.         **      0 we can stop right here and now.
  364.         **/
  365.         if ( ! numc ) return( NULL );
  366.  
  367.         /*
  368.         **      Move to the correct position
  369.         **      and render the text.
  370.         **/
  371.         Move( lvr->lvr_RPort, l, lvr->lvr_Bounds.MinY + lvr->lvr_RPort->TxBaseline );
  372.         Text( lvr->lvr_RPort, str, numc );
  373.  
  374.         /*
  375.         **      Adjust the left-edge and width to
  376.         **      get past the Name: column.
  377.         **/
  378.         l += cw;
  379.         w  = MAX(( WORD )( w - cw ), 0 );
  380.  
  381.         /*
  382.         **      Obtain Size: column width. We check it against the
  383.         **      total list width so we do not go outside the
  384.         **      given area.
  385.         **/
  386.         cw = MIN( MaxSize, w );
  387.  
  388.         /*
  389.         **      Pick up the size string or, when this
  390.         **      is a title call, the string "Size:".
  391.         **/
  392.         str = fi ? &fi->fi_Size[ 0 ] : ( UBYTE * )"Size:";
  393.  
  394.         /*
  395.         **      Compute the number of character we
  396.         **      can render.
  397.         **/
  398.         numc = TextFit( lvr->lvr_RPort, str, strlen( str ), &te, NULL, 0, cw, h );
  399.  
  400.         /*
  401.         **      If the number of characters is
  402.         **      0 we can stop right here and now.
  403.         **/
  404.         if ( ! numc ) return( NULL );
  405.  
  406.         /*
  407.         **      Move to the correct position
  408.         **      and render the text.
  409.         **/
  410.         Move( lvr->lvr_RPort, l, lvr->lvr_Bounds.MinY + lvr->lvr_RPort->TxBaseline );
  411.         Text( lvr->lvr_RPort, str, numc );
  412.  
  413.         /*
  414.         **      Adjust the left-edge and width to
  415.         **      get past the Size: column.
  416.         **/
  417.         l += cw;
  418.         w  = MAX(( WORD )( w - cw ), 0 );
  419.  
  420.         /*
  421.         **      Obtain Date column width. We check it against the
  422.         **      total list width so we do not go outside the
  423.         **      given area.
  424.         **/
  425.         cw = MIN( MaxDate, w );
  426.  
  427.         /*
  428.         **      Pick up the date string or, when this
  429.         **      is a title call, the string "Date:".
  430.         **/
  431.         str = fi ? &fi->fi_Date[ 0 ] : ( UBYTE * )"Date:";
  432.  
  433.         /*
  434.         **      Compute the number of character we
  435.         **      can render.
  436.         **/
  437.         numc = TextFit( lvr->lvr_RPort, str, strlen( str ), &te, NULL, 0, cw, h );
  438.  
  439.         /*
  440.         **      If the number of characters is
  441.         **      0 we can stop right here and now.
  442.         **/
  443.         if ( ! numc ) return( NULL );
  444.  
  445.         /*
  446.         **      Move to the correct position
  447.         **      and render the text.
  448.         **/
  449.         Move( lvr->lvr_RPort, l, lvr->lvr_Bounds.MinY + lvr->lvr_RPort->TxBaseline );
  450.         Text( lvr->lvr_RPort, str, numc );
  451.  
  452.         /*
  453.         **      Return NULL. This is important. If we return a non-NULL
  454.         **      value the listview class will think it is a pointer to
  455.         **      the text to render and try to render it.
  456.         **/
  457.         return( NULL );
  458. }
  459.  
  460. /*
  461. **      The comparrison hook. We do a simple name, dir/file
  462. **      comparrison here.
  463. **/
  464. SAVEDS ASM LONG CompareHookFunc( REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct lvCompare *lvc )
  465. {
  466.         FILEINFO                *a = ( FILEINFO * )lvc->lvc_EntryA;
  467.         FILEINFO                *b = ( FILEINFO * )lvc->lvc_EntryB;
  468.  
  469.         /*
  470.         **      First we do a type comparrison to get the
  471.         **      directories at the top of the list.
  472.         **/
  473.         if ( a->fi_IsDir && ! b->fi_IsDir      ) return( -1L );
  474.         else if ( ! a->fi_IsDir && b->fi_IsDir ) return( 1L );
  475.  
  476.         /*
  477.         **      Otherwise we do a simple, case insensitive,
  478.         **      name string comparrison.
  479.         **/
  480.         return( stricmp( &a->fi_FileName[ 0 ], &b->fi_FileName[ 0 ] ));
  481. }
  482.  
  483. /*
  484. **      A IDCMP hook for the window which allows us
  485. **      to control the listview from the keyboard.
  486. **/
  487. SAVEDS ASM VOID ScrollHookFunc( REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct IntuiMessage *msg )
  488. {
  489.         struct Window                   *window;
  490.         Object                          *lv_obj = ( Object * )hook->h_Data;
  491.  
  492.         /*
  493.         **      Obtain window pointer.
  494.         **/
  495.         GetAttr( WINDOW_Window,        obj,    ( ULONG * )&window );
  496.  
  497.         /*
  498.         **      What key is pressed?
  499.         **/
  500.         switch ( msg->Code ) {
  501.  
  502.                 case    0x4C:
  503.                         /*
  504.                         **      UP              - Move entry up.
  505.                         **      SHIFT + UP      - Move page up.
  506.                         **      CTRL + UP       - Move to the top.
  507.                         **/
  508.                         if ( msg->Qualifier & ( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT ))
  509.                                 SetGadgetAttrs(( struct Gadget * )lv_obj, window, NULL, LISTV_Select, LISTV_Select_Page_Up, TAG_END );
  510.                         else if ( msg->Qualifier & IEQUALIFIER_CONTROL )
  511.                                 SetGadgetAttrs(( struct Gadget * )lv_obj, window, NULL, LISTV_Select, LISTV_Select_First, TAG_END );
  512.                         else
  513.                                 SetGadgetAttrs(( struct Gadget * )lv_obj, window, NULL, LISTV_Select, LISTV_Select_Previous, TAG_END );
  514.                         break;
  515.  
  516.                 case    0x4D:
  517.                         /*
  518.                         **      DOWN            - Move entry down.
  519.                         **      SHIFT + DOWN    - Move page down.
  520.                         **      CTRL + DOWN     - Move to the end.
  521.                         **/
  522.                         if ( msg->Qualifier & ( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT ))
  523.                                 SetGadgetAttrs(( struct Gadget * )lv_obj, window, NULL, LISTV_Select, LISTV_Select_Page_Down, TAG_END );
  524.                         else if ( msg->Qualifier & IEQUALIFIER_CONTROL )
  525.                                 SetGadgetAttrs(( struct Gadget * )lv_obj, window, NULL, LISTV_Select, LISTV_Select_Last, TAG_END );
  526.                         else
  527.                                 SetGadgetAttrs(( struct Gadget * )lv_obj, window, NULL, LISTV_Select, LISTV_Select_Next, TAG_END );
  528.  
  529.                         break;
  530.  
  531.                 case    0x43:
  532.                 case    0x44:
  533.                         /*
  534.                         **      RETURN or ENTER - Report the listview ID to the event handler.
  535.                         **/
  536.                         DoMethod( obj, WM_REPORT_ID, (( struct Gadget * )lv_obj )->GadgetID, 0L );
  537.                         break;
  538.         }
  539. }
  540.  
  541. /*
  542. **      The hook structures as added to the
  543. **      listview object and window object.
  544. **
  545. **      If your compiler complaints about the
  546. **      HOOKFUNC typedef uncomment the below line.
  547. **/
  548.  
  549. /* typedef ULONG (*HOOKFUNC)(); */
  550.  
  551. struct Hook ResourceHook = { NULL, NULL, (HOOKFUNC)ResourceHookFunc, NULL, NULL };
  552. struct Hook DisplayHook  = { NULL, NULL, (HOOKFUNC)DisplayHookFunc,  NULL, NULL };
  553. struct Hook CompareHook  = { NULL, NULL, (HOOKFUNC)CompareHookFunc,  NULL, NULL };
  554. struct Hook ScrollHook   = { NULL, NULL, (HOOKFUNC)ScrollHookFunc,   NULL, NULL };
  555.  
  556. /*
  557. **      Scan the directory "name".
  558. **/
  559. VOID ScanDirectory( UBYTE *name, Object *obj )
  560. {
  561.         struct ExAllControl             *eac;
  562.         struct ExAllData                *ead, *tmp;
  563.         struct FileInfoBlock            *fib;
  564.         BPTR                             lock;
  565.         BOOL                             ismore;
  566.  
  567.         /*
  568.         **      We need to recompute the columns.
  569.         **/
  570.         ReCompCols = TRUE;
  571.  
  572.         /*
  573.         **      Get a lock to the directory.
  574.         **/
  575.         if ( lock = Lock( name, ACCESS_READ )) {
  576.                 /*
  577.                 **      Allocate a FileInfoBlock structure.
  578.                 **/
  579.                 if ( fib = ( struct FileInfoBlock * )AllocDosObject( DOS_FIB, NULL )) {
  580.                         /*
  581.                         **      Examine the lock.
  582.                         **/
  583.                         if ( Examine( lock, fib )) {
  584.                                 /*
  585.                                 **      Is this a directory?
  586.                                 **/
  587.                                 if ( fib->fib_DirEntryType > 0 ) {
  588.                                         /*
  589.                                         **      Allocate ExAll() control structure.
  590.                                         **/
  591.                                         if ( eac = ( struct ExAllControl * )AllocDosObject( DOS_EXALLCONTROL, NULL )) {
  592.                                                 /*
  593.                                                 **      Set key to NULL.
  594.                                                 **/
  595.                                                 eac->eac_LastKey = NULL;
  596.                                                 /*
  597.                                                 **      Allocate ExAll() buffer.
  598.                                                 **/
  599.                                                 if ( ead = ( struct ExAllData * )AllocVec( 10 * sizeof( struct ExAllData ), MEMF_PUBLIC )) {
  600.                                                         /*
  601.                                                         **      Read directory.
  602.                                                         **/
  603.                                                         do {
  604.                                                                 /*
  605.                                                                 **      Fill buffer.
  606.                                                                 **/
  607.                                                                 ismore = ExAll( lock, ead, 10 * sizeof( struct ExAllData ), ED_DATE, eac );
  608.  
  609.                                                                 /*
  610.                                                                 **      Errors? Done?
  611.                                                                 **/
  612.                                                                 if (( ! ismore ) && ( IoErr() != ERROR_NO_MORE_ENTRIES ))
  613.                                                                         break;
  614.  
  615.                                                                 /*
  616.                                                                 **      Entries read?
  617.                                                                 **/
  618.                                                                 if ( ! eac->eac_Entries )
  619.                                                                         continue;
  620.  
  621.                                                                 /*
  622.                                                                 **      Pick up data pointer.
  623.                                                                 **/
  624.                                                                 tmp = ead;
  625.  
  626.                                                                 /*
  627.                                                                 **      Add the entries.
  628.                                                                 **/
  629.                                                                 do {
  630.                                                                         AddEntry( NULL, obj, tmp, LVAP_SORTED );
  631.                                                                         /*
  632.                                                                         **      Next...
  633.                                                                         **/
  634.                                                                         tmp = tmp->ed_Next;
  635.                                                                 } while ( tmp );
  636.                                                         } while ( ismore );
  637.                                                         /*
  638.                                                         **      Deallocate ExAll() buffer.
  639.                                                         **/
  640.                                                         FreeVec( ead );
  641.                                                 }
  642.                                                 /*
  643.                                                 **      Deallocate ExAll() control structure.
  644.                                                 **/
  645.                                                 FreeDosObject( DOS_EXALLCONTROL, eac );
  646.                                         }
  647.                                 }
  648.                         }
  649.                         /*
  650.                         **      Deallocate FileInfoBlock structure.
  651.                         **/
  652.                         FreeDosObject( DOS_FIB, fib );
  653.                 }
  654.                 /*
  655.                 **      Release lock.
  656.                 **/
  657.                 UnLock( lock );
  658.         }
  659. }
  660.  
  661. /*
  662. **      And were off...
  663. **/
  664. #define ID_QUIT                 1
  665. #define ID_LIST                 2
  666. #define ID_NEWDIR               3
  667.  
  668. int main( int argc, char *argv[] )
  669. {
  670.         struct ReadArgs                 *ra;
  671.         struct Window                   *win;
  672.         Object                          *WO_DirWin, *GO_DirList, *GO_Quit, *GO_NewDir;
  673.         FILEINFO                        *fi;
  674.         ULONG                            dname = 0L, signal, rc;
  675.         UBYTE                            name[ 512 ], *ptr;
  676.         BOOL                             running = TRUE;
  677.  
  678.         /*
  679.         **      Parse command line?
  680.         **/
  681.         if ( ra = ReadArgs( "NAME", &dname, NULL )) {
  682.                 /*
  683.                 **      Copy the name into the buffer.
  684.                 **/
  685.                 if ( dname ) strcpy( name, ( UBYTE * )dname );
  686.                 else         name[ 0 ] = 0;
  687.                 /*
  688.                 **      Create the listview object.
  689.                 **/
  690.                 GO_DirList = ListviewObject,
  691.                         LISTV_ResourceHook,             &ResourceHook,
  692.                         LISTV_DisplayHook,              &DisplayHook,
  693.                         LISTV_TitleHook,                &DisplayHook,
  694.                         LISTV_CompareHook,              &CompareHook,
  695.                         GA_ID,                          ID_LIST,
  696.                 EndObject;
  697.                 /*
  698.                 **      Put it in the IDCMP hook.
  699.                 **/
  700.                 ScrollHook.h_Data = ( APTR )GO_DirList;
  701.                 /*
  702.                 **      Create the window.
  703.                 **/
  704.                 WO_DirWin = WindowObject,
  705.                         WINDOW_Title,           "MultiCol",
  706.                         WINDOW_RMBTrap,         TRUE,
  707.                         WINDOW_ScaleWidth,      50,
  708.                         WINDOW_ScaleHeight,     30,
  709.                         WINDOW_SmartRefresh,    TRUE,
  710.                         WINDOW_IDCMPHookBits,   IDCMP_RAWKEY,
  711.                         WINDOW_IDCMPHook,       &ScrollHook,
  712.                         WINDOW_MasterGroup,
  713.                                 VGroupObject, HOffset( 4 ), VOffset( 4 ), Spacing( 4 ),
  714.                                         StartMember,
  715.                                                 VGroupObject,
  716.                                                         StartMember, GO_DirList, EndMember,
  717.                                                         StartMember,
  718.                                                                 GO_NewDir = KeyString( NULL, name, 512, ID_NEWDIR ), FixMinHeight,
  719.                                                         EndMember,
  720.                                                 EndObject,
  721.                                         EndMember,
  722.                                         StartMember,
  723.                                                 HGroupObject,
  724.                                                         VarSpace( DEFAULT_WEIGHT ),
  725.                                                         StartMember, GO_Quit = KeyButton( "_Quit", ID_QUIT ), EndMember,
  726.                                                         VarSpace( DEFAULT_WEIGHT ),
  727.                                                 EndObject, FixMinHeight,
  728.                                         EndMember,
  729.                                 EndObject,
  730.                 EndObject;
  731.  
  732.                 /*
  733.                 **      Window created OK?
  734.                 **/
  735.                 if ( WO_DirWin ) {
  736.                         /*
  737.                         **      Add gadget key.
  738.                         **/
  739.                         if ( GadgetKey( WO_DirWin, GO_Quit, "q" )) {
  740.                                 /*
  741.                                 **      Open the window.
  742.                                 **/
  743.                                 if ( win = WindowOpen( WO_DirWin )) {
  744.                                         /*
  745.                                         **      Obtain signal mask.
  746.                                         **/
  747.                                         GetAttr( WINDOW_SigMask, WO_DirWin, &signal );
  748.                                         /*
  749.                                         **      Read in the directory.
  750.                                         **/
  751.                                         WindowBusy( WO_DirWin );
  752.                                         ScanDirectory( name, GO_DirList );
  753.                                         WindowReady( WO_DirWin );
  754.                                         /*
  755.                                         **      Refresh the list.
  756.                                         **/
  757.                                         RefreshList( win, GO_DirList );
  758.                                         /*
  759.                                         **      Poll messages...
  760.                                         **/
  761.                                         do {
  762.                                                 Wait( signal );
  763.                                                 while (( rc = HandleEvent( WO_DirWin )) != WMHI_NOMORE ) {
  764.                                                         switch ( rc ) {
  765.  
  766.                                                                 case    ID_QUIT:
  767.                                                                 case    WMHI_CLOSEWINDOW:
  768.                                                                         running = FALSE;
  769.                                                                         break;
  770.  
  771.                                                                 case    ID_LIST:
  772.                                                                         /*
  773.                                                                         **      Get selected entry.
  774.                                                                         **/
  775.                                                                         if ( fi = ( FILEINFO * )FirstSelected( GO_DirList )) {
  776.                                                                                 /*
  777.                                                                                 **      Is the entry a directory?
  778.                                                                                 **/
  779.                                                                                 if ( fi->fi_IsDir ) {
  780.                                                                                         /*
  781.                                                                                         **      AddPart() the name to the buffer.
  782.                                                                                         **/
  783.                                                                                         AddPart( name, &fi->fi_FileName[ 0 ], 512 );
  784.                                                                                         /*
  785.                                                                                         **      Refresh the string gadget.
  786.                                                                                         **/
  787.                                                                                         SetGadgetAttrs(( struct Gadget * )GO_NewDir, win, NULL, STRINGA_TextVal, name, TAG_END );
  788.                                                                                         /*
  789.                                                                                         **      Re-read the list.
  790.                                                                                         **/
  791.                                                                                         refreshDir:
  792.                                                                                         WindowBusy( WO_DirWin );
  793.                                                                                         ClearList( win, GO_DirList );
  794.                                                                                         ScanDirectory( name, GO_DirList );
  795.                                                                                         RefreshList( win, GO_DirList );
  796.                                                                                         WindowReady( WO_DirWin );
  797.                                                                                 }
  798.                                                                         }
  799.                                                                         break;
  800.  
  801.                                                                 case    ID_NEWDIR:
  802.                                                                         /*
  803.                                                                         **      Copy the new name to the buffer.
  804.                                                                         **/
  805.                                                                         GetAttr( STRINGA_TextVal, GO_NewDir, ( ULONG * )&ptr );
  806.                                                                         strcpy( name, ptr );
  807.                                                                         goto refreshDir;
  808.                                                         }
  809.                                                 }
  810.                                         } while ( running );
  811.                                 }
  812.                         }
  813.                         /*
  814.                         **      Kill the object.
  815.                         **/
  816.                         DisposeObject( WO_DirWin );
  817.                 }
  818.                 /*
  819.                 **      Delete the ReadArgs structure.
  820.                 **/
  821.                 FreeArgs( ra );
  822.         }
  823. }
  824.  
  825. #ifdef _DCC
  826. int wbmain( struct WBStartup *wbs )
  827. {
  828.         return( main( 0, NULL ));
  829. }
  830. #endif
  831.  
  832. /*
  833.  *      $Log: multicol.c,v $
  834.  * Revision 1.3  1994/11/20  13:06:11  jaba
  835.  * Added an IDCMP hook to control the listview by keyboard.
  836.  *
  837.  * Revision 1.2  1994/11/16  16:41:03  jaba
  838.  * Change the register specs to lowercase for SAS.
  839.  *
  840.  * Revision 1.1  1994/11/13  14:49:35  jaba
  841.  * Initial revision
  842.  *
  843.  */
  844.